package com.daffodil.framework.shiro.session;

import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.BeanUtils;

import com.daffodil.framework.constant.ShiroConstants;
import com.daffodil.util.StringUtils;

/**
 * web在线会话管理
 * @author yweijian
 * @date 2019年8月20日
 * @version 1.0
 */
public class OnlineSessionManager extends DefaultWebSessionManager{
	
	@Override
	public void setAttribute(SessionKey sessionKey, Object attributeKey, Object value) throws InvalidSessionException {
		super.setAttribute(sessionKey, attributeKey, value);
		if (value != null && isNeedMarkAttributeChanged(attributeKey)) {
			OnlineSession session = getOnlineSession(sessionKey);
			session.markAttributeChanged();
		}
	}

	@Override
	public Object removeAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException {
		Object removed = super.removeAttribute(sessionKey, attributeKey);
		if (removed != null) {
			OnlineSession session = getOnlineSession(sessionKey);
			session.markAttributeChanged();
		}
		return removed;
	}
	
	/**
	 * 是否需要标记为会话属性变更
	 * @param attributeKey
	 * @return
	 */
	private boolean isNeedMarkAttributeChanged(Object attributeKey) {
		if (attributeKey == null) {
			return false;
		}
		String attributeKeyStr = attributeKey.toString();
		if (attributeKeyStr.startsWith("org.springframework")) {
			return false;
		}
		if (attributeKeyStr.startsWith("javax.servlet")) {
			return false;
		}
		if (attributeKeyStr.equals(ShiroConstants.CURRENT_USERNAME)) {
			return false;
		}
		return true;
	}
	
	/**
	 * 复制会话消息
	 * @param sessionKey
	 * @return
	 */
	private OnlineSession getOnlineSession(SessionKey sessionKey) {
		OnlineSession onlineSession = null;
		Session session = super.doGetSession(sessionKey);
		if (StringUtils.isNotNull(session)) {
			onlineSession = new OnlineSession();
			BeanUtils.copyProperties(session, onlineSession);
		}
		return onlineSession;
	}
}
